#include <iostream>
#include <sys/epoll.h>
#include "Log.hpp"
#include <string>

#define default_epfd -1;

const int ep_size = 128;

namespace Epoll
{
    class Epoller
    {
    public:
        Epoller() : _epfd(default_epfd) {}
        ~Epoller()
        {
            if (_epfd >= 0)
            {
                lg.LogMessage(Info, "close epfd success\n");
                close(_epfd);
            }
        }
        void InitEpoller()
        {
            _epfd = epoll_create(ep_size);
            if (_epfd == -1)
            {
                lg.LogMessage(Fatal, "epoll create failed, error is %s, code: %d\n", strerror(errno), errno);
                exit(0);
            }
            lg.LogMessage(Info, "epoll create success, epfd = %d\n", _epfd);
        }
        void AddEvent(const int sock_fd, uint32_t events)
        {
            struct epoll_event ev;
            ev.events = events;
            ev.data.fd = sock_fd;

            int n = ::epoll_ctl(_epfd, EPOLL_CTL_ADD, sock_fd, &ev);
            if (n < 0)
            {
                lg.LogMessage(Error, "epoll add failed, error is %s, code: %d\n".strerror(errno), errno);
            }
        }
        void DelEvent(const int sock_fd)
        {
            // 删除关心事件，不需要设置事件，直接删去文件描述符
            int n = epoll_ctl(_epfd, EPOLL_CTL_DEL, sock_fd, nullptr);
            if(n<0)
            {
                lg.LogMessage(Error, "epoll delete failed, error is %s, code: %d\n".strerror(errno), errno);
            }
        }
        void ModEvent(const int sock_fd, uint32_t events)
        {
        }
        int WaitEpoller(struct epoll_event *events, int max_events, int timeout)
        {
            int n = ::epoll_wait(_epfd, events, max_events, timeout);
            return n;
        }

    private:
        int _epfd;
    };
}